package org.web.accesscontrollist.server.biz.impl;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.web.accesscontrollist.sdk.dto.OperatorDTO;
import org.web.accesscontrollist.server.AclServerHelper;
import org.web.accesscontrollist.server.biz.impl.constant.AclBusinessConstant;
import org.web.accesscontrollist.server.domain.AclBusinessLineDO;
import org.web.accesscontrollist.server.domain.AclBusinessLineOwnerDO;
import org.web.accesscontrollist.server.domain.query.QueryAclBusinessLine;
import org.web.accesscontrollist.server.domain.query.QueryAclBusinessLineOwner;
import org.web.accesscontrollist.server.service.AclBusinessLineOwnerService;
import org.web.accesscontrollist.server.service.AclBusinessLineService;
import org.web.accesscontrollist.server.service.OperatorService;
import org.web.base.domain.ResultDO;
import org.web.base.domain.exception.ResultMessageEnum;
import org.web.base.domain.exception.ServiceException;
import org.web.base.domain.helper.ResultHelper;
import org.web.base.domain.helper.ServiceExceptionHelper;
import org.web.base.helper.EnumHelper;

import javax.annotation.Resource;
import java.util.UUID;

@Service("aclBusinessLineServiceBiz")
public class AclBusinessLineServiceBiz implements AclBusinessConstant {

    @Resource
    private AclBusinessLineService aclBusinessLineService;

    @Resource
    private AclBusinessLineOwnerService aclBusinessLineOwnerService;

    @Resource
    private OperatorService operatorService;

    /***
     * 校验业务线是否存在，如果存在，则校验权限； 如果不存在，则构建缺省业务线。
     * （1）校验业务线是否存在。
     * （2）不存在，则构建缺省业务线。
     * （3）存在，校验权限。
     */
    public void judgeOperatorOrBuildDefaultBusinessLine(OperatorDTO operatorDTO) throws ServiceException {
        // 判断业务线businessLine是否存在。            // 根据accessKey判断权限。
        QueryAclBusinessLine queryAclBusinessLine = new QueryAclBusinessLine();
        queryAclBusinessLine.setBusinessLine(operatorDTO.getBusinessLine());
        AclBusinessLineDO aclBusinessLineDOFromDB = aclBusinessLineService.selectOneAclBusinessLine(queryAclBusinessLine);
        if (ObjectUtils.isEmpty(aclBusinessLineDOFromDB)) {
            // 业务线为空，缺省构建一个新的业务线。
            AclBusinessLineDO aclBusinessLineDO = AclServerHelper.buildAclBusinessLineDOByOperatorDTO(operatorDTO);
            aclBusinessLineDO.setBusinessLineDescription("缺省创建一条新的业务线。请后续完善此业务线描述。");
            ResultDO<AclBusinessLineDO> saveBusinessLineResultDO = saveBusinessLine(aclBusinessLineDO);
            if (saveBusinessLineResultDO.isFailed()) {
                throw ServiceExceptionHelper.buildServiceException(saveBusinessLineResultDO);
            }
        } else {
            // 业务线不为空的场合，根据accessKey 校验逻辑。
            operatorService.judgeOperatorByAccessKey(operatorDTO.getBusinessLine(), operatorDTO.getAccessKey());
        }

    }

    public ResultDO<AclBusinessLineDO> saveBusinessLine(AclBusinessLineDO aclBusinessLineDO) {
        ResultDO<AclBusinessLineDO> result = new ResultDO<>();
        try {
            // 第一步，校验acl_business_line记录是否存在。
            QueryAclBusinessLine queryAclBusinessLine = new QueryAclBusinessLine();
            queryAclBusinessLine.setBusinessLine(aclBusinessLineDO.getBusinessLine());
            AclBusinessLineDO aclBusinessLineDOFromDB = aclBusinessLineService.selectOneAclBusinessLine(queryAclBusinessLine);
            if (ObjectUtils.isNotEmpty(aclBusinessLineDOFromDB)) {
                // 已经存在的处理场景，校验是否有权限。
                AclBusinessLineOwnerDO aclBusinessLineOwnerDOFromDB = getAclBusinessLineOwnerDOByOwnerAndBusinessLine(aclBusinessLineDOFromDB.getOperatorNum(), aclBusinessLineDOFromDB.getBusinessLine());
                if (ObjectUtils.isEmpty(aclBusinessLineOwnerDOFromDB)) {
                    throw ServiceExceptionHelper.buildServiceException(ResultMessageEnum.DATA_NO_PRIVILEGE, "业务线已存在，但没有操作权限。");
                }
                AclBusinessLineDO updateAclBusinessLineDO = new AclBusinessLineDO();
                BeanUtils.copyProperties(updateAclBusinessLineDO, aclBusinessLineDO);
                updateAclBusinessLineDO.setAclBusinessLineId(aclBusinessLineDOFromDB.getAclBusinessLineId());
                if (StringUtils.isNotBlank(updateAclBusinessLineDO.getAccessKey()) && !StringUtils.equals(EnumHelper.DELETE.Y.name(), updateAclBusinessLineDO.getIsDelete())) {
                    aclBusinessLineService.updateAclBusinessLineByAclBusinessLineId(updateAclBusinessLineDO);
                }
                result.setMessage(SAVE_BUSINESS_LINE_MESSAGE_UPDATE_SUCCESS);
            } else {
                // 新增记录场景。
                if (StringUtils.isBlank(aclBusinessLineDO.getAccessKey())) {
                    aclBusinessLineDO.setAccessKey(UUID.randomUUID().toString());
                }
                if (StringUtils.isBlank(aclBusinessLineDO.getBusinessLineDescription())) {
                    aclBusinessLineDO.setBusinessLineDescription(DEFAULT_BUSINESS_LINE_DESCRIPTION);
                }
                result.setDomain(aclBusinessLineDO);
                aclBusinessLineService.insertAclBusinessLine(aclBusinessLineDO);
                AclBusinessLineOwnerDO aclBusinessLineOwnerDOFromDB = getAclBusinessLineOwnerDOByOwnerAndBusinessLine(aclBusinessLineDO.getOperatorNum(), aclBusinessLineDO.getBusinessLine());
                if (ObjectUtils.isEmpty(aclBusinessLineOwnerDOFromDB)) {
                    // 新创建业务线，默认创建者是这个业务线的owner.
                    AclBusinessLineOwnerDO aclBusinessLineOwnerDO = new AclBusinessLineOwnerDO();
                    aclBusinessLineOwnerDO.setBusinessLine(aclBusinessLineDO.getBusinessLine());
                    aclBusinessLineOwnerDO.setOwnerNum(aclBusinessLineDO.getOperatorNum());
                    aclBusinessLineOwnerDO.setOwnerName(aclBusinessLineDO.getOperatorName());
                    aclBusinessLineOwnerDO.setOperatorNum(aclBusinessLineDO.getOperatorNum());
                    aclBusinessLineOwnerDO.setOperatorName(aclBusinessLineDO.getOperatorName());
                    aclBusinessLineOwnerService.insertAclBusinessLineOwner(aclBusinessLineOwnerDO);
                }
                result.setMessage(SAVE_BUSINESS_LINE_MESSAGE_INSERT_SUCCESS);
            }
        } catch (Exception e) {
            result = ResultHelper.buildResultDOByException(e, aclBusinessLineDO);
        }
        return result;
    }

    protected AclBusinessLineOwnerDO getAclBusinessLineOwnerDOByOwnerAndBusinessLine(String ownerNum, String businessLine) {
        QueryAclBusinessLineOwner queryAclBusinessLineOwner = new QueryAclBusinessLineOwner();
        queryAclBusinessLineOwner.setBusinessLine(businessLine);
        queryAclBusinessLineOwner.setOwnerNum(ownerNum);
        return aclBusinessLineOwnerService.selectOneAclBusinessLineOwner(queryAclBusinessLineOwner);
    }
}